package io.xccit.aischool.controller;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import io.swagger.annotations.ApiParam;
import io.xccit.aischool.entity.Admin;
import io.xccit.aischool.entity.LoginForm;
import io.xccit.aischool.entity.Student;
import io.xccit.aischool.entity.Teacher;
import io.xccit.aischool.service.IAdminService;
import io.xccit.aischool.service.IStudentService;
import io.xccit.aischool.service.ITeacherService;
import io.xccit.aischool.util.*;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;

import javax.imageio.ImageIO;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.IOException;
import java.util.LinkedHashMap;
import java.util.Map;
import java.util.UUID;

/**
 * @author CH_ywx
 * @date 2023-06-06
 * @description 非表格验证的controller
 */
@Api(tags = "系统服务接口")
@RestController
@RequestMapping("/sms/system")
public class SystemController {

    @Autowired
    private IAdminService adminService;
    @Autowired
    private ITeacherService teacherService;
    @Autowired
    private IStudentService studentService;

    /**
     * 拿到token验证用户信息
     * @param token
     * @return
     */
    @ApiOperation("登录后跳转至首页")
    @GetMapping("/getInfo")
    public Result getInfoByToken(@ApiParam("用户token信息") @RequestHeader("token") String token){
        //token过期
        if(JwtHelper.isExpiration(token)){
            return Result.build(null, ResultCodeEnum.TOKEN_ERROR);//构建一个Result提示用户token已过期
        }
        //token未过期,从token中解析用户信息
        Long userId = JwtHelper.getUserId(token);
        Integer userType = JwtHelper.getUserType(token);
        //准备一个map封装用户信息
        Map<String, Object> map = new LinkedHashMap<>();
        //根据用户类型查找相应的用户信息
        switch (userType){
            case 1:
                Admin admin = adminService.getUserByID(userId);
                map.put("userType",1);
                map.put("user",admin);
                break;
            case 2:
                Student student = studentService.getUserByID(userId);
                map.put("userType",2);
                map.put("user",student);
                break;
            case 3:
                Teacher teacher = teacherService.getUserByID(userId);
                map.put("userType",3);
                map.put("user",teacher);
                break;
        }
        return Result.ok(map);
    }
    /**
     * 用户登录
     * @param loginForm
     * @param request
     * @return
     */
    @ApiOperation("用户登录")
    @PostMapping("/login")
    public Result login(@ApiParam("登录用户请求体") @RequestBody LoginForm loginForm,HttpServletRequest request){
        HttpSession session = request.getSession();
        String sessionVerifiCode = (String) session.getAttribute("verifiCode");//取出session中的验证码
        String verifiCode = loginForm.getVerifiCode();//用户输入的验证码
        //session中的验证码为空
        if ("".equals(sessionVerifiCode) || sessionVerifiCode == null){
            return Result.fail().message("验证码失效,清刷新后重试");
        }
        //不判断验证码大小写,如果输入的验证码有误
        if (!sessionVerifiCode.equalsIgnoreCase(verifiCode)){
            return Result.fail().message("验证码输入错误,请检查后重试");
        }
        //验证码通过,移除session中的验证码
        session.removeAttribute("verifiCode");
        //准备一个Map存放信息
        Map<String, Object> map = new LinkedHashMap<>();
        //分用户类型校验
        switch (loginForm.getUserType()){
            //管理员
            case 1:
                try {
                    Admin admin = adminService.login(loginForm);
                    //用户不为空,验证通过
                    if (admin != null){
                        //生成一个token
                        String token = JwtHelper.createToken(admin.getId(), 1);
                        map.put("token",token);//token交由map存放
                    }else {
                        throw new RuntimeException("用户名或密码有误");
                    }
                    return Result.ok(map);
                } catch (RuntimeException e) {
                    return Result.fail().message(e.getMessage());
                }
            //学生
            case 2:
                try {
                    Student student = studentService.login(loginForm);
                    //用户不为空,验证通过
                    if (student != null){
                        //生成一个token
                        String token = JwtHelper.createToken(student.getId(), 2);
                        map.put("token",token);//token交由map存放
                    }else {
                        throw new RuntimeException("用户名或密码有误");
                    }
                    return Result.ok(map);
                } catch (RuntimeException e) {
                    return Result.fail().message(e.getMessage());
                }
            case 3:
                try {
                    Teacher teacher = teacherService.login(loginForm);
                    //用户不为空,验证通过
                    if (teacher != null){
                        //生成一个token
                        String token = JwtHelper.createToken(teacher.getId(), 3);
                        map.put("token",token);//token交由map存放
                    }else {
                        throw new RuntimeException("用户名或密码有误");
                    }
                    return Result.ok(map);
                } catch (RuntimeException e) {
                    return Result.fail().message(e.getMessage());
                }
        }
        return Result.fail().message("用户不存在,请检查登录信息");
    }

    /**
     * 获取验证码
     *
     * @param request
     * @param response
     */
    @ApiOperation("获取验证码接口")
    @GetMapping("/getVerifiCodeImage")
    public void getVerifyCodeImage(HttpServletRequest request, HttpServletResponse response) {
        //验证码图片
        BufferedImage codeImage = CreateVerifiCodeImage.getVerifiCodeImage();
        char[] c = CreateVerifiCodeImage.getVerifiCode();
        String verifiCode = new String(c);//获取的验证码
        HttpSession session = request.getSession();//获取session
        session.setAttribute("verifiCode", verifiCode);//将验证码存入session域
        System.out.println(UUID.randomUUID() +"验证码:"+verifiCode);
        try {
            //将验证码写入到页面
            ImageIO.write(codeImage, "JPEG", response.getOutputStream());
        } catch (IOException e) {
            throw new RuntimeException(e);
        }
    }

    /**
     *
     * @param multipartFile 文件
     * @return 文件相对路径
     */
    @ApiOperation("用户头像上传接口")
    @PostMapping("/headerImgUpload")
    public Result<String> headerImageUpload(@RequestPart("multipartFile") MultipartFile multipartFile){
        //获取图片位置
        String originalFilename = multipartFile.getOriginalFilename();
        int i = originalFilename.lastIndexOf(".");
        String uuid = UUID.randomUUID().toString();
        String newFileName = uuid.concat(originalFilename.substring(i)); //新文件名
        String filePath = "E:/IdeaProjects/AISchool/target/classes/public/upload/".concat(newFileName); //文件保存的位置
        try {
            //将文件保存到该路径
            multipartFile.transferTo(new File(filePath));
        } catch (IOException e) {
            throw new RuntimeException(e);
        }
        String path = "upload/".concat(newFileName);
        return Result.ok(path);
    }

    @ApiOperation("个人密码修改")
    @PostMapping("/updatePwd/{oldPassword}/{newPassword}")
    public Result updatePwd(@ApiParam("用户旧密码") @PathVariable String oldPassword,
                                     @ApiParam("用户新密码") @PathVariable String newPassword,
                                     @ApiParam("token") @RequestHeader("token") String token
                                    ){
        if (JwtHelper.isExpiration(token)) {
            //token过期
            return Result.fail(ResultCodeEnum.TOKEN_ERROR).message("Token过期,请重新登录");
        }
        Integer userType = JwtHelper.getUserType(token);
        Long userId = JwtHelper.getUserId(token);
        switch (userType){
            case 1:
                QueryWrapper<Admin> queryWrapper = new QueryWrapper<>();
                queryWrapper.eq("id",userId);
                Admin admin = adminService.getOne(queryWrapper);//查询出的admin
                if (admin.getPassword().equals(MD5.encrypt(oldPassword))) {
                    admin.setPassword(MD5.encrypt(newPassword));
                }
                adminService.saveOrUpdate(admin);
                return Result.ok().message("密码修改成功");
            case 2:
                QueryWrapper<Student> studentQueryWrapper = new QueryWrapper<>();
                studentQueryWrapper.eq("id",userId);
                Student student = studentService.getOne(studentQueryWrapper);
                if (student.getPassword().equals(MD5.encrypt(oldPassword))) {
                    student.setPassword(MD5.encrypt(newPassword));
                }
                studentService.saveOrUpdate(student);
                return Result.ok().message("密码修改成功");
            case 3:
                QueryWrapper<Teacher> teacherQueryWrapper = new QueryWrapper<>();
                teacherQueryWrapper.eq("id",userId);
                Teacher teacher = teacherService.getOne(teacherQueryWrapper);
                if (teacher.getPassword().equals(MD5.encrypt(oldPassword))) {
                    teacher.setPassword(MD5.encrypt(newPassword));
                }
                teacherService.saveOrUpdate(teacher);
                return Result.ok().message("密码修改成功");
        }
        return Result.fail().message("请检查旧密码");
    }
}
